package com.bluedot.www.core.utils;

import com.bluedot.www.core.pojo.BO.MailBo;
import com.sun.mail.util.MailSSLSocketFactory;

import javax.mail.*;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.security.GeneralSecurityException;
import java.util.Properties;
import java.util.Random;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;


/**
 * 邮件工具类
 *
 * @author He Peng
 * @version 1.0
 * @date 2021/9/2 10:40
 */
public class MailUtil {

    /**
     * 手动创建线程池
     */
    private static ExecutorService pool = Executors.newCachedThreadPool();

    private static String smtpSslEnable;
    private static String smtpAuth;
    private static String host;
    private static String transportProtocol;
    private static String sender;
    private static String password;


    /**
     * 多线程发送邮件
     */
    public static void fixThreadSendmail(String location, MailBo mailBo) {
        pool.execute(new Runnable() {
            @Override
            public void run() {
                sendMail(location, mailBo);
            }
        });
    }

    /**
     * <p>发送邮件</p>
     * 发送邮件的速度较慢，建议单独使用线程发送
     * 代码示例<pre>
     *     public static void main(String[] args) {
     *         MailBo mailBo = new MailBo("orangejam123@163.com", "测试发送是否正常", "这是正文内容<img src='https://jiutwo-picbed.oss-cn-shenzhen.aliyuncs.com/img/0021.png'>");
     *         sendMail("application.properties", mailBo);
     *     }
     * </pre>
     *
     * @param location: 配置文件位置
     * @param mail:     邮件内容
     * @return boolean
     * @author He Peng
     * @date 2021/9/2 14:01
     */
    public static boolean sendMail(String location, MailBo mail) {

        try {
            //0、初始化属性
            initProperty(location);

            // 2、创建
            Session session = initSession();

            //2、通过session获取transport对象
            Transport transport = session.getTransport();

            //3、通过transport对象邮箱用户名和授权码连接邮箱服务器
            transport.connect(host, sender, password);

            //4、创建邮件,传入session对象
            MimeMessage mimeMessage = complexEmail(session, sender, mail);
            //5、发送邮件
            transport.sendMessage(mimeMessage, mimeMessage.getAllRecipients());

            //6、关闭连接
            transport.close();

        } catch (IOException e) {
            e.printStackTrace();
        } catch (GeneralSecurityException | MessagingException e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }


    private static Session initSession() throws GeneralSecurityException {
        Properties prop = new Properties();
        prop.setProperty("mail.host", host);  //设置邮件服务器
        prop.setProperty("mail.transport.protocol", transportProtocol); // 邮件发送协议
        prop.setProperty("mail.smtp.auth", smtpAuth); // 需要验证用户名密码

        // 邮箱设置SSL加密
        MailSSLSocketFactory sf = new MailSSLSocketFactory();
        sf.setTrustAllHosts(true);
        prop.put("mail.smtp.ssl.enable", smtpSslEnable);
        prop.put("mail.smtp.ssl.socketFactory", sf);

        //1、创建定义整个应用程序所需的环境信息的 Session 对象
        return Session.getDefaultInstance(prop, new Authenticator() {
            @Override
            protected PasswordAuthentication getPasswordAuthentication() {
                //传入发件人的姓名和授权码
                return new PasswordAuthentication(sender, password);
            }
        });
    }


    private static void initProperty(String location) throws IOException {
        Properties properties = new Properties();
        // 使用ClassLoader加载properties配置文件生成对应的输入流
        InputStream in = MailUtil.class.getClassLoader().getResourceAsStream(location);
        // 使用properties对象加载输入流
        properties.load(in);
        //获取key对应的value值
        host = properties.getProperty("mail.host");
        transportProtocol = properties.getProperty("mail.transport.protocol");
        smtpAuth = properties.getProperty("mail.smtp.auth");
        smtpSslEnable = properties.getProperty("mail.smtp.ssl.enable");
        sender = properties.getProperty("mail.sender");
        password = properties.getProperty("mail.password");
    }


    /**
     * 拼接生成 Message 消息
     *
     * @param session:
     * @param sender:
     * @param mailBo:
     * @return javax.mail.internet.MimeMessage
     * @author He Peng
     * @date 2021/9/2 13:55
     */
    private static MimeMessage complexEmail(Session session, String sender, MailBo mailBo) throws MessagingException {
        //消息的固定信息
        MimeMessage mimeMessage = new MimeMessage(session);

        //发件人
        mimeMessage.setFrom(new InternetAddress(sender));
        //收件人
        mimeMessage.setRecipient(Message.RecipientType.TO, new InternetAddress(mailBo.getSendTo()));
        //邮件标题
        mimeMessage.setSubject(mailBo.getSubject());

        /*邮件内容*/

        // 准备文本
        MimeBodyPart text = new MimeBodyPart();
        text.setContent(mailBo.getContent(), "text/html;charset=utf-8");

        // 拼装邮件正文
        MimeMultipart mimeMultipart = new MimeMultipart();
        // 图片
        if (mailBo.getImage() != null) {
            for (MimeBodyPart image : mailBo.getImage()) {
                mimeMultipart.addBodyPart(image);
            }
        }
        // 文本
        mimeMultipart.addBodyPart(text);
        mimeMultipart.setSubType("related");//文本和图片内嵌成功

        //将拼装好的正文内容设置为主体
        MimeBodyPart contentText = new MimeBodyPart();
        contentText.setContent(mimeMultipart);

        //拼接附件
        MimeMultipart allFile = new MimeMultipart();
        allFile.addBodyPart(contentText);//正文
        allFile.setSubType("mixed"); //正文和附件都存在邮件中，所有类型设置为mixed
        // 拼接附件
        if (mailBo.getAttachment() != null) {
            for (MimeBodyPart mimeBodyPart : mailBo.getAttachment()) {
                allFile.addBodyPart(mimeBodyPart);
            }
        }

        //放到Message消息中
        mimeMessage.setContent(allFile);
        mimeMessage.saveChanges();//保存修改

        return mimeMessage;
    }


    /**
     * 随机生成6位数的验证码
     *
     * @param
     * @return java.lang.String
     * @author jiangnan
     * @date 2021/9/2 14:52
     */
    public static String getCode() {
        String sources = "0123456789";
        Random rand = new Random();
        StringBuffer flag = new StringBuffer();
        for (int j = 0; j < 6; j++) {
            flag.append(sources.charAt(rand.nextInt(9)) + "");
        }
        return flag.toString();
    }


    /**
     * 读取html
     *
     * @param file 模板文件
     * @return java.lang.StringBuilder
     * @author jiangnan
     * @date 2021/9/11 15:33
     */
    public static String readHTML(File file) throws IOException {
        InputStreamReader isReader = null;
        BufferedReader bufReader = null;
        StringBuffer buf = new StringBuffer();
        try {
            isReader = new InputStreamReader(new FileInputStream(file), StandardCharsets.UTF_8);
            bufReader = new BufferedReader(isReader, 1);
            String data;
            while ((data = bufReader.readLine()) != null) {
                buf.append(data);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            assert isReader != null;
            isReader.close();
            assert bufReader != null;
            bufReader.close();

        }


        return buf.toString();
    }
}
